package ua.races.dao;

import ua.races.relultObjects.FullBet;
import ua.races.relultObjects.FullRace;
import ua.races.vo.Client;
import ua.races.vo.HorseRace;
import ua.races.vo.Race;
import ua.races.vo.*;

import java.io.IOException;
import java.sql.Date;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

public interface Dao {
    /**
     * Creates connection pool and sets up max number of connections in this pool
     *
     * @throws java.sql.SQLException if something goes wrong
     * @throws IOException if something goes wrong
     */
    void start() throws SQLException, IOException;

    /**
     * Destroys connection pool
     *
     * @throws java.sql.SQLException if something goes wrong
     */
    void stop() throws SQLException;

    /**
     * Returns list of all horses in the database
     *
     * @return list of all horses in the database
     * @throws java.sql.SQLException if something goes wrong
     */
    List<Horse> findAllHorses() throws SQLException;

    /**
     * Returns list of all Horseraces in the database
     *
     * @return list of all Horseraces in the database
     * @throws java.sql.SQLException if something goes wrong
     */
    List<HorseRace> findAllHorseRaces() throws SQLException;

    /**
     * Returns list of all Clients in the database
     *
     * @return list of all Clients in the database
     * @throws java.sql.SQLException if something goes wrong
     */
    List<Client> findAllClients() throws SQLException;

    /**
     * Returns list of all Races in the database
     *
     * @return list of all Races in the database
     * @throws java.sql.SQLException if something goes wrong
     */
    List<Race> findAllRaces() throws SQLException;

    /**
     * Returns list of all Bets in the database
     *
     * @return list of all Bets in the database
     * @throws java.sql.SQLException if something goes wrong
     */
    List<Bet> findAllBets() throws SQLException;

    /**
     * Adds new client
     *
     * @param client - client to add
     * @return 1 if operation completed successful
     * @throws java.sql.SQLException if something goes wrong
     */
    int addNewClient(Client client) throws SQLException;

    /**
     * Returns list of all types of bets
     *
     * @return list of all types of bets
     * @throws java.sql.SQLException if something goes wrong
     */
    List<BetType> findAllBetTypes() throws SQLException;

    /**
     * Returns results for every horse in the database
     *
     * @return Map where Key is a horse and Value is array of all places
     * @throws java.sql.SQLException if something goes wrong
     */
    Map<Horse, List<Integer>> getHorseHistory() throws SQLException;

    /**
     * Returns list of all horses which take part in race
     *
     * @param race - race
     * @return List of all horses which take part in race
     * @throws java.sql.SQLException if something goes wrong
     */
    List<Horse> getHorsesInRace(Race race) throws SQLException;

    /**
     * Returns Client object with this email
     *
     * @param email - email
     * @return Client with this email
     * @throws java.sql.SQLException if something goes wrong
     */
    Client findClientByEmail(String email) throws SQLException;

    /**
     * Adds revenue to client's account if his bet won
     * @param races which should be processed
     * @return number of changed records
     * @throws SQLException if something goes wrong
     */
    int giveRevenueToClients(List<Race> races) throws SQLException;

     /**
     * Returns list of all available rases where choosen horse will take part
     *
     * @param horse - choosen horse
     * @return list of all available rases where choosen horse will take part
     * @throws SQLException if something goes wrong
     */
    List<Race> findAllRacesWithHorse(Horse horse) throws SQLException;

    /**
     * Just finds Race by Race_ID
     * @param raceId - Id of the race
     * @return Race with certain ID
     * @throws SQLException if something goes wrong
     */
    Race findRaceById(long raceId) throws SQLException;

    /**
     * Just finds client by client_ID
     * @param clientId - Id of the client
     * @return client with certain ID
     * @throws SQLException if something goes wrong
     */
    Client findClientById(long clientId) throws SQLException;

    /**
     * Just finds horse by horse_ID
     * @param horseId - Id of the horse
     * @return horse with certain ID
     * @throws SQLException if something goes wrong
     */
    Horse findHorseById(long horseId) throws SQLException;

    /**
     * Just finds betType by betType_ID
     * @param betTypeId - Id of the betType
     * @return Type of BET with certain ID
     * @throws SQLException if something goes wrong
     */
    BetType findBetTypeById(long betTypeId) throws SQLException;

    /**
     * Just finds bet by BET_ID
     * @param betId - Id of the bet
     * @return Bet with certain ID
     * @throws SQLException if something goes wrong
     */
    Bet findBetById(long betId) throws SQLException;

    /**
     * Returns Staff object with this email
     *
     * @param email - email
     * @return Staff with this email
     * @throws java.sql.SQLException if something goes wrong
     */
    Staff findStaffByEmail(String email) throws SQLException;

    /**
     * This method returns list of FullRace objects
     * and uses just for visualization data on jsp page
     * @param races - simple list of dto-races
     * @return list of FullRace objects
     * @throws java.sql.SQLException if something goes wrong
     */
    List<FullRace> getFullRaces(List<Race> races) throws SQLException;

    /**
     * This method returns list of FullBet objects
     * and uses just for visualization data on jsp page
     * @param bets - simple list of dto-bets
     * @return list of FullBet objects
     * @throws java.sql.SQLException if something goes wrong
     */
    List<FullBet> getFullBets(List<Bet> bets) throws SQLException;

    /**
     * Returns list which contains all horses takin part in current race
     * @param race - current race
     * @return list which contains all horses takin part in current race
     * @throws SQLException if something goes wrong
     */
    List<Horse> findAllHorseInRace(Race race) throws SQLException;

    /**
     * Returns statistics of all horses in the db
     * @param history - number of races you want to review
     * @return statistics of all horses in the db
     * @throws SQLException if something goes wrong
     */
    Map<Horse,Map<Date,Integer>> horseStatistics(int history) throws SQLException;
    
}